#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2024/5/8
# @Author  : suk
# @File    : product.py
# @Software: PyCharm
import json
from io import BytesIO

from barcode import Code128, EAN13, Code39,CODABAR
from barcode.writer import ImageWriter
from django.http import HttpResponse
from django.shortcuts import render, get_object_or_404
from django.views import View
from rest_framework.decorators import action

from common.API import res_josn_data
from common.API.log import exec_log
from common.filter.format import vague_filter
from common.layuiview.layuiviewsets import ModelViewSetLayui
from drf_auth_system.settings import admin_id, UPLOAD_PRODUCT_DIR

from product_drf.models import Product, ProductUploadImage
from product_drf.serializers import ProductQueryModelSerializer
from system_manage.models import Department


class ProductPage(View):
    http_method_names = ['get']

    def get(self, request, *args, **kwargs):
        departments = Department.objects.values('pk', 'name').all()
        return render(request, 'product_manage/page.html', {'departments': departments})


class ProductGenericView(ModelViewSetLayui):
    queryset = Product.objects.filter().all()
    serializer_class = ProductQueryModelSerializer

    def list(self, request, *args, **kwargs):
        page = request.GET.get('page', 1)
        limit = request.GET.get('limit', 10)
        post_data_str = request.GET.get('Params', None)
        print(request.GET)
        number = (int(page) - 1) * int(limit)  # 每页开始的序号

        if post_data_str is None:
            return res_josn_data.table_api(data=[])
        json_data = json.loads(post_data_str)
        fk_department = json_data.get('fk_department', None)
        try:
            json_data.pop('fk_department')
        except Exception:
            pass
        filters = vague_filter(json_data)  # 生成过滤器参数
        # 过滤库房和管理员
        if admin_id == request.session.get('role_id'):
            if fk_department:
                filters.update({'fk_department__exact': request.GET.get('fk_department', fk_department)})
        else:
            filters.update({'fk_department__exact': request.session.get('dept_id')})
        print('filters:', filters)
        queryset = self.get_serializer_class().Meta.model.objects.filter(**filters).order_by('-id')  # 过滤
        page = self.paginate_queryset(queryset)  # 分页
        serializer = self.get_serializer(queryset, many=True)  # 序列化

        if page is None:
            return res_josn_data.table_api(data=[])
        else:
            serializer_page = self.get_serializer(page, many=True)

            # print('返回数据:', serializer.data)
            return res_josn_data.table_api(count=len(serializer.data), data=serializer_page.data, number=number)

    def create(self, request, *args, **kwargs):
        print('request.data:', request.data)
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        row_obj = serializer.save()
        files = request.FILES.getlist('file')
        if files:
            # 有文件上传则落盘
            for file in files:
                UPLOAD_PRODUCT_DIR.joinpath(str(row_obj.id)).mkdir(parents=True, exist_ok=True)
                with UPLOAD_PRODUCT_DIR.joinpath(str(row_obj.id), file.name).open('wb') as file_obj:
                    for chunk in file.chunks():
                        file_obj.write(chunk)
                ProductUploadImage.objects.create(filename=file.name, fk_product_id=row_obj.pk).save()
        exec_log(request, is_access=True, desc=serializer.data)
        return res_josn_data.table_success(msg='创建成功', data=serializer.data)

    def destroy(self, request, *args, **kwargs):
        instance = self.get_object()
        upload_images = ProductUploadImage.objects.filter(fk_product_id=instance.pk).all()
        for image in upload_images:
            print(UPLOAD_PRODUCT_DIR.joinpath(str(image.fk_product_id), image.filename))
            UPLOAD_PRODUCT_DIR.joinpath(str(image.fk_product_id), image.filename).unlink(missing_ok=True)
            try:
                UPLOAD_PRODUCT_DIR.joinpath(str(image.fk_product_id)).rmdir()
            except Exception:
                pass
        instance.delete()
        print(f'id:{instance} 已删除')
        exec_log(request, is_access=True, desc=f'{instance} 已删除')
        # return Response(status=status.HTTP_204_NO_CONTENT)
        return res_josn_data.success_api('删除成功')

    @action(methods=['delete'], detail=False)
    def multiple_delete(self, request, *args, **kwargs):
        post_data_str = request.POST.get('Params', None)
        post_data = json.loads(post_data_str)
        # pks = request.query_params.get('pks', None)  # 获取要删除的对象们的主键值
        # if not pks:
        #     return Response(status=status.HTTP_404_NOT_FOUND)
        for item in post_data:
            id_value = item['id']
            queryset = self.filter_queryset(self.get_queryset())
            instance = get_object_or_404(queryset, id=int(id_value))
            upload_images = ProductUploadImage.objects.filter(fk_product_id=instance.pk).all()
            for image in upload_images:
                print(UPLOAD_PRODUCT_DIR.joinpath(str(image.fk_product_id), image.filename))
                UPLOAD_PRODUCT_DIR.joinpath(str(image.fk_product_id), image.filename).unlink(missing_ok=True)
                try:
                    UPLOAD_PRODUCT_DIR.joinpath(str(image.fk_product_id)).rmdir()
                except Exception:
                    pass
            instance.delete()
            print(f'id:{id_value} 已删除')
            exec_log(request, is_access=True, desc=f'id:{id_value} 已删除')
        return res_josn_data.success_api('删除成功')
        # return Response(status=status.HTTP_204_NO_CONTENT)

    def update(self, request, *args, **kwargs):
        print('put request.data:', request.data)
        partial = kwargs.pop('partial', False)
        instance = self.get_object()
        serializer = self.get_serializer(instance, data=request.data, partial=partial)
        serializer.is_valid(raise_exception=True)

        row_obj = serializer.save()
        # 处理上传文件
        files = request.FILES.getlist('file')
        if files:
            # 先删除原来的数据
            upload_images = ProductUploadImage.objects.filter(fk_product_id=instance.pk).all()
            for image in upload_images:
                print(UPLOAD_PRODUCT_DIR.joinpath(str(image.fk_product_id), image.filename))
                UPLOAD_PRODUCT_DIR.joinpath(str(image.fk_product_id), image.filename).unlink(missing_ok=True)
                try:
                    UPLOAD_PRODUCT_DIR.joinpath(str(image.fk_product_id)).rmdir()
                except Exception:
                    pass
            # 删除上传文件数据库的数据
            ProductUploadImage.objects.filter(fk_product_id=instance.pk).delete()
            # 有文件上传则落盘
            for file in files:
                UPLOAD_PRODUCT_DIR.joinpath(str(row_obj.id)).mkdir(parents=True, exist_ok=True)
                with UPLOAD_PRODUCT_DIR.joinpath(str(row_obj.id), file.name).open('wb') as file_obj:
                    for chunk in file.chunks():
                        file_obj.write(chunk)
                ProductUploadImage.objects.create(filename=file.name, fk_product_id=row_obj.pk).save()

        if getattr(instance, '_prefetched_objects_cache', None):
            # If 'prefetch_related' has been applied to a queryset, we need to
            # forcibly invalidate the prefetch cache on the instance.
            instance._prefetched_objects_cache = {}

        # return Response(serializer.data)
        exec_log(request, is_access=True, desc=serializer.data)
        print('更新serializer.data:', serializer.data)
        return res_josn_data.success_api('更新成功')


class ProductAdd(View):
    http_method_names = ['get']

    def get(self, request, *args, **kwargs):
        if admin_id == request.session.get('role_id'):
            departments = Department.objects.values('pk', 'name').all()
        else:
            dept_id = request.session.get('dept_id')
            departments = Department.objects.filter(pk=dept_id).values('pk', 'name').all()
        return render(request, 'product_manage/add.html', {'departments': departments})


class ProductEdit(View):
    http_method_names = ['get', 'post']

    def get(self, request, *args, **kwargs):
        if admin_id == request.session.get('role_id'):
            departments = Department.objects.values('pk', 'name').all()
        else:
            dept_id = request.session.get('dept_id')
            departments = Department.objects.filter(pk=dept_id).values('pk', 'name').all()
        return render(request, 'product_manage/edit.html', {'departments': departments})


# 条形码生成
class ProductCode(View):
    http_method_names = ['get']

    def get(self, request, *args, **kwargs):
        pk = request.GET.get('id')
        ean = Code39(pk, writer=ImageWriter(),add_checksum=False)
        stream = BytesIO()
        # EAN13(pk,writer=ImageWriter()).write(stream)
        # Code128('P' + str(pk).zfill(10), writer=ImageWriter()).write(stream)
        # Code39(pk, writer=ImageWriter(),add_checksum=False).write(stream)
        ean.write(stream)
        return HttpResponse(stream.getvalue(), content_type="image/png")


class ConsoleSignImage(View):
    http_method_names = ['get']

    def get(self, request, *args, **kwargs):
        # 查看附件
        pk = request.GET.get('id')
        fk_product = request.GET.get('fk_product')
        upload_image_obj = ProductUploadImage.objects.filter(pk=pk, fk_product_id=fk_product).first()
        if not upload_image_obj:
            return res_josn_data.fail_api('图片不存在')

        file_obj = UPLOAD_PRODUCT_DIR.joinpath(fk_product, upload_image_obj.filename)
        print(file_obj)
        if file_obj.exists():
            response = HttpResponse(file_obj.open('rb').read(), content_type="image/png")
            return response
